Pacotes

library(tidyverse)
## ── Attaching packages ─────────────────────────────────────────── tidyverse 1.2.1 ──
## ✔ ggplot2 3.1.0     ✔ purrr   0.2.5
## ✔ tibble  1.4.2     ✔ dplyr   0.7.7
## ✔ tidyr   0.8.1     ✔ stringr 1.3.1
## ✔ readr   1.1.1     ✔ forcats 0.3.0
## ── Conflicts ────────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
library(ggplot2)

Ler dados

imdb <- read_rds("../dados/imdb.rds")
imdb <- imdb %>% mutate(lucro = receita - orcamento)

Pergunta: será que filmes com maior orçamento tendem a arrecadar mais?

Gráfico de dispersão: arrecadação vs orçamento

ggplot(imdb) +
  geom_point(mapping = aes(x = orcamento, y = receita))
## Warning: Removed 733 rows containing missing values (geom_point).

Vamos acrescentar a reta y = x para visualizar a quantidade de filmes que não se pagaram.

imdb %>%
  ggplot() +
  geom_point(mapping = aes(x = orcamento, y = receita)) +
  geom_abline(intercept = 0, slope = 1, color = "red")
## Warning: Removed 733 rows containing missing values (geom_point).

Também podemos usar a cor dos pontos para visualizar os filmes que não se pagaram.

imdb %>%
  mutate(
    lucro = ifelse(lucro <= 0, "Não", "Sim")
  ) %>%
  ggplot() +
  geom_point(mapping = aes(x = orcamento, y = receita, color = lucro))
## Warning: Removed 733 rows containing missing values (geom_point).

# O que aconteceria se usássemos uma variável numérica para representar a cor dos pontos?

Vamos arrumar os labels.

imdb %>%
  mutate(
    lucro = ifelse(lucro <= 0, "Não", "Sim")
  ) %>%
  filter(!is.na(lucro)) %>% 
  ggplot() +
  geom_point(mapping = aes(x = orcamento, y = receita, color = lucro)) +
  labs(x = "Orçamento", y = "Arrecadação", color = "Houve lucro?") 

Vamos também mudar as labels nos eixos.

imdb %>%
  mutate(
    lucro = ifelse(lucro <= 0, "Não", "Sim")
  ) %>%
  filter(!is.na(lucro)) %>% 
  ggplot() +
  geom_point(mapping = aes(x = orcamento, y = receita, color = lucro)) +
  labs(x = "Orçamento", y = "Arrecadação", color = "Houve lucro?") +
  scale_y_continuous(label = scales::dollar_format()) +
  scale_x_continuous(label = scales::dollar_format()) +
  scale_color_manual(values = c("red", "green"), labels = c("N", "S"))

Também podemos colocar as variáveis na escala de milhões.

imdb %>%
  mutate(
    lucro = ifelse(lucro <= 0, "Não", "Sim")
  ) %>% 
  mutate(
    receita = receita/1000000,
    orcamento = orcamento/1000000
  ) %>% 
  ggplot() +
  geom_point(mapping = aes(x = orcamento, y = receita, color = lucro)) +
  labs(
    x = "Orçamento  (em milhôes de dólares)", 
    y = "Arrecadação (em milhôes de dólares)", 
    color = "Houve lucro?"
  ) +
  scale_y_continuous(label = scales::dollar_format()) +
  scale_x_continuous(label = scales::dollar_format())
## Warning: Removed 733 rows containing missing values (geom_point).

Exercício: será que filmes mais caros tendem a receber uma nota maior?

  1. Crie um gráfico de dispersão da nota do imdb pelo orçamento.

  2. Pinte todos os pontos do gráfico de azul.

  3. Refaça o gráfico do item 1. apenas para filmes com classificação etária livre. Também refaça para os filmes com classificação etária “a partir de 13 anos”.

Podemos usar facets para fazer um gráfico para cada nível de uma variável.

imdb %>%
  filter(classificacao %in% c("Livre", "A partir de 13 anos")) %>%
  ggplot() +
  geom_point(aes(x = orcamento, y = nota_imdb)) +
  facet_wrap(~classificacao)
## Warning: Removed 85 rows containing missing values (geom_point).

A função facet_grid() permite combinar os níveis de duas variáveis.

imdb %>%
  filter(classificacao %in% c("Livre", "A partir de 13 anos")) %>%
  mutate(ano_cat = ifelse(ano < 2000, "Antigos", "Recentes")) %>%
  mutate(ano_class = paste(classificacao, ano_cat)) %>% 
  ggplot() +
  geom_point(aes(x = orcamento, y = nota_imdb, color = ano_class)) +
  facet_grid(ano_cat ~ classificacao)
## Warning: Removed 85 rows containing missing values (geom_point).

Pergunta: quais são os diretores que fizeram mais filmes e quantos filmes eles fizeram?

Podemos fazer um gráfico de barras.

imdb %>%
  ggplot() +
  geom_bar(aes(x = diretor))

Vamos visualizar apenas os 10 diretores com mais filmes.

imdb %>% 
  dplyr::count(diretor) %>% 
  arrange(desc(n)) %>% 
  filter(!is.na(diretor)) %>% 
  dplyr::top_n(10, n) %>%
  ggplot() +
  geom_bar(aes(x = diretor, y = n), stat = "identity")

imdb %>% 
  dplyr::count(diretor) %>% 
  arrange(desc(n)) %>% 
  filter(!is.na(diretor)) %>% 
  dplyr::top_n(10, n) %>%
  ggplot() +
  geom_col(aes(x = diretor, y = n))

Vamos arrumar os labels rotacionando os nomes.

imdb %>% 
  count(diretor) %>% 
  arrange(desc(n)) %>% 
  filter(!is.na(diretor)) %>% 
  top_n(10, n) %>%
  ggplot() +
  geom_bar(aes(x = diretor, y = n), stat = "identity") +
  theme(axis.text.x = element_text(angle = 45, vjust = 0.5))

Também seria interessante ordenar as barras de forma crescente. Para isso, precisamos lidar com fatores.

Um fator é a representação numérica de uma variavel categórica dentro do R. Ele será mostrado como texto (categoria/level), mas por trás ele é tratado como um inteiro.

O melhor pacote para tratar fatores é o forcats.

library(forcats)

imdb %>% 
  count(diretor) %>% 
  arrange(desc(n)) %>% 
  filter(!is.na(diretor)) %>% 
  top_n(10, n) %>%
  mutate(
    diretor = fct_reorder(diretor, n)
  ) %>% 
  ggplot() +
  geom_bar(aes(x = diretor, y = n), stat = "identity") +
  theme(axis.text.x = element_text(angle = 45, vjust = 0.5))

Também podemos escolher outra cor para as barras.

imdb %>% 
  count(diretor) %>% 
  arrange(desc(n)) %>% 
  filter(!is.na(diretor)) %>% 
  top_n(10, n) %>%
  mutate(
    diretor = fct_reorder(diretor, n)
  ) %>% 
  ggplot() +
  geom_bar(
    aes(x = diretor, y = n), 
    stat = "identity", 
    color = "darkblue",
    fill = "pink"
  ) +
  theme(axis.text.x = element_text(angle = 45, vjust = 0.5))

imdb %>% 
  count(diretor) %>% 
  arrange(desc(n)) %>% 
  filter(!is.na(diretor)) %>% 
  top_n(10, n) %>%
  mutate(
    diretor = fct_reorder(diretor, n)
  ) %>% 
  ggplot() +
  geom_bar(
    aes(x = diretor, y = n, fill = diretor), 
    stat = "identity", 
    color = "darkblue",
    show.legend = FALSE
  ) +
  theme(axis.text.x = element_text(angle = 45, vjust = 0.5))

Boxplots

imdb %>% 
  filter(!is.na(diretor)) %>%
  group_by(diretor) %>% 
  filter(n() >= 15) %>% 
  ggplot() +
  geom_boxplot(aes(x = diretor, y = lucro))
## Warning: Removed 10 rows containing non-finite values (stat_boxplot).

Ordenando pela mediana.

imdb %>% 
  filter(!is.na(diretor)) %>%
  group_by(diretor) %>% 
  filter(n() >= 15) %>%
  ungroup() %>% 
  mutate(
    diretor = fct_reorder(diretor, lucro, .fun = max, na.rm = TRUE)
  ) %>% 
  ggplot() +
  geom_boxplot(aes(x = diretor, y = lucro, fill = diretor)) +
  theme(axis.text.x = element_text(angle = 45, vjust = 0.5))
## Warning: Removed 10 rows containing non-finite values (stat_boxplot).

Também poderíamos fazer um histograma para avaliar a distribuição.

imdb %>% 
  filter(diretor == "Steven Spielberg") %>%
  ggplot() +
  geom_histogram(aes(x = lucro))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 1 rows containing non-finite values (stat_bin).

Deixando mais bonito.

imdb %>% 
  filter(diretor == "Steven Spielberg") %>%
  ggplot() +
  geom_histogram(
    aes(x = lucro), 
    binwidth = 1000000,
    color = "white"
  )
## Warning: Removed 1 rows containing non-finite values (stat_bin).

Exercício

  1. Refaça o último gráfico utilizando a agora a variável orçamento como resposta.

2.a Selecione um gênero e visualize os diretores com mais filmes dentro desse gênero.

2.b Estude a distribuição da variável lucro para cada diretor.

Pergunta: qual o comportamento das notas dos filmes do Spielberg no IMDB ao longo do tempo?

Vamos fazer um gráfico de linhas das notas pelo ano.

imdb %>% 
  filter(diretor == "Steven Spielberg") %>% 
  ggplot() +
  geom_line(aes(x = ano, y = nota_imdb))

Vamos agregar os dados para termos apenas uma medida por ano.

imdb %>% 
  filter(diretor == "Steven Spielberg") %>%
  group_by(ano) %>% 
  summarise(nota_media = mean(nota_imdb, na.rm = TRUE)) %>% 
  ggplot() +
  geom_line(aes(x = ano, y = nota_media))

Podemos misturar dois geom's.

imdb %>% 
  filter(diretor == "Steven Spielberg") %>%
  group_by(ano) %>% 
  summarise(nota_media = mean(nota_imdb, na.rm = TRUE)) %>% 
  ggplot() +
  geom_line(aes(x = ano, y = nota_media), alpha = 0.1) +
  geom_point(aes(x = ano, y = nota_media), alpha = 0.1) +
  geom_text(aes(x = ano, y = nota_media , label = nota_media))

Neste caso, é útil reescreveremos o código da seguinte maneira.

imdb %>% 
  filter(diretor == "Steven Spielberg") %>%
  group_by(ano) %>% 
  summarise(nota_media = mean(nota_imdb, na.rm = TRUE)) %>% 
  ggplot(aes(x = ano, y = nota_media)) +
  geom_point(alpha = 0.1) +
  geom_line(alpha = 0.1) +
  geom_text(aes(label = nota_media))

Exercícios

Repita as análises acima, agora para os atores (vamos começar utilizando apenas a coluna ator_1:

  1. Selecione os atores com mais filmes. Visualize quem são os atores e o número de filmes que eles fizeram. Você pode ou não fazer a análise para um gênero.

  2. Estude a distribuição do orçamento e do lucro dos filmes desses atores.

  3. Selecione um dos atores e estude a nota de seus filmes no IMDB ao longo do tempo.

E se quiséssemos utilizar as 3 colunas de atores?

imdb %>% 
  gather(posicao, ator, ator_1, ator_2, ator_3) %>% 
  View

Exercícios

Repita a análise anterior, utilizando agora todas as colunas de atores, e veja se você mudaria de opinião sobre o ator a ser escolhido.

Misc de ggplot2

Temas.

imdb %>%
  mutate(
    lucro = ifelse(lucro <= 0, "Não", "Sim")
  ) %>% 
  mutate(
    receita = receita/1000000,
    orcamento = orcamento/1000000
  ) %>% 
  ggplot() +
  geom_point(mapping = aes(x = orcamento, y = receita, color = lucro)) +
  labs(
    x = "Orçamento (em milhões de dólares)", 
    y = "Arrecadação (em milhões de dólares)", 
    color = "Houve lucro?"
  ) +
  scale_y_continuous(label = scales::dollar_format()) +
  scale_x_continuous(label = scales::dollar_format()) +
  theme_bw()
## Warning: Removed 733 rows containing missing values (geom_point).

Títulos

imdb %>%
  mutate(
    lucro = ifelse(lucro <= 0, "Não", "Sim")
  ) %>% 
  mutate(
    receita = receita/1000000,
    orcamento = orcamento/1000000
  ) %>% 
  ggplot() +
  geom_point(mapping = aes(x = orcamento, y = receita, color = lucro)) +
  labs(
    x = "Orçamento", 
    y = "Arrecadação", 
    color = "Houve lucro?"
  ) +
  scale_y_continuous(label = scales::dollar_format()) +
  scale_x_continuous(label = scales::dollar_format()) +
  theme_minimal() +
  ggtitle("Arrecadação vs Orçamento (em milhões de dólares)") +
  theme(plot.title = element_text(hjust = 0.5))
## Warning: Removed 733 rows containing missing values (geom_point).

Legendas

imdb %>%
  mutate(
    lucro = ifelse(lucro <= 0, "Não", "Sim")
  ) %>% 
  mutate(
    receita = receita/1000000,
    orcamento = orcamento/1000000
  ) %>% 
  ggplot() +
  geom_point(mapping = aes(x = orcamento, y = receita, color = lucro)) +
  labs(
    x = "Orçamento", 
    y = "Arrecadação", 
    color = "Houve lucro?"
  ) +
  scale_y_continuous(label = scales::dollar_format()) +
  scale_x_continuous(label = scales::dollar_format()) +
  theme_minimal() +
  ggtitle("Arrecadação vs Orçamento (em milhões de dólares)") +
  theme(legend.position = "bottom")
## Warning: Removed 733 rows containing missing values (geom_point).

gplot2 extensions: https://www.ggplot2-exts.org/

library(ggridges)
## 
## Attaching package: 'ggridges'
## The following object is masked from 'package:ggplot2':
## 
##     scale_discrete_manual
imdb %>%
  filter(ano > 2005) %>% 
  mutate(ano = as.factor(ano)) %>% 
  ggplot(aes(y = ano, x = receita, fill = ano)) +
  geom_density_ridges(na.rm = TRUE, show.legend = FALSE)
## Picking joint bandwidth of 17300000

Foco

imdb %>%
  filter(ano > 2005) %>% 
  mutate(ano = as.factor(ano)) %>% 
  ggplot(aes(y = ano, x = receita, fill = ano)) +
  geom_density_ridges(na.rm = TRUE) +
  coord_cartesian(xlim = c(-30000000, 200000000))
## Picking joint bandwidth of 17300000

Exercícios

  1. Faça um gráfico para visualizar as 10 maiores bilheterias de 2016.

  2. Quantos filmes “são feitos por ano”?

Outros pacotes interessantes para gráficos:

Plotly

library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
p <- imdb %>% 
  filter(diretor == "Steven Spielberg") %>%
  ggplot(aes(x = ano, y = nota_imdb, text = titulo)) +
  geom_point() +
  geom_line(aes(group = 1))

ggplotly(p, tooltip = "text")

Patchwork

devtools::install_github("thomasp85/patchwork")
## Skipping install of 'patchwork' from a github remote, the SHA1 (fd7958ba) has not changed since last install.
##   Use `force = TRUE` to force installation
library(patchwork)

p1 <- imdb %>% 
  filter(!is.na(diretor)) %>%
  group_by(diretor) %>% 
  filter(n() >= 15) %>%
    filter(n() >= 15) %>%
  ungroup() %>% 
  mutate(
    diretor = as.factor(diretor),
    diretor = fct_reorder(diretor, lucro, .fun = mean, na.rm = TRUE)
  ) %>% 
  ggplot() +
  geom_boxplot(aes(x = diretor, y = lucro)) +
  theme(axis.text.x = element_text(angle = 45, vjust = 0.5))

p2 <- imdb %>% 
  filter(diretor == "Steven Spielberg") %>% 
  ggplot() +
  geom_histogram(
    aes(x = lucro),
    fill = "lightblue", 
    color = "darkblue", 
    binwidth = 100000000
  )


p1 + p2
## Warning: Removed 10 rows containing non-finite values (stat_boxplot).
## Warning: Removed 1 rows containing non-finite values (stat_bin).